package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.dto.*;
import com.heima.comment.entity.ApComment;
import com.heima.comment.entity.ApCommentLike;
import com.heima.comment.entity.ApCommentRepay;
import com.heima.comment.entity.UpdateCommentMessage;
import com.heima.comment.feign.ArticleFeign;
import com.heima.comment.feign.UserFeign;
import com.heima.comment.mongo.IApCommentRepository;
import com.heima.comment.service.IApCommentService;
import com.heima.comment.service.IAuditService;
import com.heima.comment.service.ICommentRepayService;
import com.heima.comment.vo.ApCommentVo;
import com.heima.comment.vo.ApCommentListVo;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.util.AppThreadLocalUtil;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author WSJ
 * @Date 2022-03-29-9:36
 * @Version 1.0 （版本号）
 */
@Service
public class ApCommentServiceImpl implements IApCommentService {
    @Autowired
    private IAuditService auditService;
    @Autowired
    private ArticleFeign articleFeign;

//    @Autowired
//    private BehaviorFeign behaviorFeign;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private MongoTemplate template;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    @Override
    public ResponseResult save(CommentSaveDto dto) {
        //保存文章评论
        //必须登录后才能评论
        User user = AppThreadLocalUtil.get();
        if (user==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //判断评论内容不能为空白，不能超过140字
        if (dto==null|| StringUtils.isEmpty(dto.getContent())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_NOT_NULL);
        }
        if (dto.getContent().length()>280) {
            return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_IS_TOO_LONG);
        }
        //判断是否允许被评论
        ResponseResult<ApArticle> responseResult = articleFeign.getOperation(dto.getArticleId());
        if (responseResult.getCode()== AppHttpCodeEnum.SUCCESS.getCode()) {
            ApArticle apArticle = responseResult.getData();
            if (!apArticle.getIsComment()) {
                return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_IS_CLOSE);
            }
        }
        //对文本内容做审核
        boolean audit = auditService.audit(dto.getContent());
        if (!audit) {
            return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_IS_FAILED);
        }
        //通过则保存评论
//        //获取行为实体id
//        EntryDto entryDto = new EntryDto();
//        entryDto.setUserId(user.getId());
//        ResponseResult<ApBehaviorEntry> result = behaviorFeign.saveEntry(entryDto);
//        ApBehaviorEntry entry=null;
//        if (result.getCode()== AppHttpCodeEnum.SUCCESS.getCode()) {
//            entry = result.getData();
//        }
        //获取文章作者信息
//        ResponseResult<ApAuthor> authorResponseResult = articleFeign.find(dto.getArticleId());
//        ApAuthor apAuthor=null;
//        if (authorResponseResult.getCode()== AppHttpCodeEnum.SUCCESS.getCode()) {
//            apAuthor = authorResponseResult.getData();
//        }
        //获取评论者头像
        ResponseResult<ApUser> userFeignImage = userFeign.findImage(user.getId());
        ApUser apUser=null;
        if (userFeignImage.getCode()== AppHttpCodeEnum.SUCCESS.getCode()) {
           apUser = userFeignImage.getData();
        }
        //构建评论对象
        ApComment comment = new ApComment();
        comment.setAuthorId(apUser.getId());
        comment.setAuthorName(apUser.getName());
        comment.setContent(dto.getContent());
        comment.setCreatedTime(new Date());
        comment.setEntryId(dto.getArticleId());
        comment.setFlag(0);
        comment.setReply(0);
        comment.setLikes(0L);
        comment.setType(0);
        comment.setImage(apUser.getImage());
        //保存评论
        template.save(comment);
        //发送kafka,保存评论数据
        UpdateArticleMessage message = new UpdateArticleMessage();
        message.setArticleId(dto.getArticleId());
        message.setType(2);
        message.setAdd(1);
        String jsonString = JSON.toJSONString(message);
        kafkaTemplate.send(hotArticleScoreTopic, jsonString);
        //返回
        return ResponseResult.okResult();
    }

    @Value("${topic.hotArticleScoreTopic}")
    private String hotArticleScoreTopic;


    @Override
    public ResponseResult load(CommentDto dto) {
        //分页查询评论列表
        //构建查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("entryId").is(dto.getArticleId()));
        PageRequest pageRequest = PageRequest.of(dto.getPage().intValue()-1, dto.getSize(), Sort.Direction.DESC, "createdTime");
        query.with(pageRequest);
        List<ApComment> apComments = template.find(query, ApComment.class);
        //查询对评论是否点赞
        List<ApCommentVo> voList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(apComments)) {
            for (ApComment apComment : apComments) {
                Query queryLike = new Query();
                queryLike.addCriteria(Criteria.where("commentId").is(apComment.getId().toHexString()));
                ApCommentLike apCommentLike = template.findOne(queryLike, ApCommentLike.class);
                //构建vo
                ApCommentVo vo = new ApCommentVo();
                BeanUtils.copyProperties(apComment,vo);
                if (apCommentLike!=null) {
                    vo.setOperation(apCommentLike.getOperation());
                }
                voList.add(vo);
            }
        }
        //返回
        return ResponseResult.okResult(voList);
    }

    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //点赞、取消点赞
        //必须登录后才能点赞
        User user = AppThreadLocalUtil.get();
        if (user==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //构建对象
        //先查询是否存在记录
        Query query = new Query();
        query.addCriteria(Criteria.where("commentId").is(dto.getCommentId()));
        query.addCriteria(Criteria.where("authorId").is(user.getId()));
        ApCommentLike commentLike = template.findOne(query, ApCommentLike.class);
        if (commentLike==null) {
            commentLike = new ApCommentLike();
            commentLike.setCommentId(dto.getCommentId());
            commentLike.setOperation(dto.getOperation().intValue());
            commentLike.setAuthorId(user.getId());
        }else {
            commentLike.setOperation(dto.getOperation().intValue());
        }
        //保存
        template.save(commentLike);
        //发送kafka
        UpdateCommentMessage message = new UpdateCommentMessage();
        message.setAdd(dto.getOperation()==0?1:-1);
        message.setCommentId(dto.getCommentId());
        message.setType(1);
        String jsonString = JSON.toJSONString(message);
        kafkaTemplate.send("comment_repay_score_topic", jsonString);
        //返回
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult list(CommentDto dto) {
        //查看评论列表
        //构建查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("entryId").is(dto.getArticleId()));
        PageRequest pageRequest = PageRequest.of(dto.getPage().intValue()-1, dto.getSize(), Sort.Direction.DESC, "createdTime");
        query.with(pageRequest);
        List<ApComment> commentList = template.find(query, ApComment.class);
        //查询评论的评论
        List<ApCommentListVo> voList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(commentList)) {
            for (ApComment apComment : commentList) {
                Query queryRepay = new Query();
                queryRepay.addCriteria(Criteria.where("entryId").is(apComment.getEntryId()));
                List<ApCommentRepay> commentRepays = template.find(queryRepay, ApCommentRepay.class);
                ApCommentListVo vo = new ApCommentListVo();
                vo.setApComments(apComment);
                vo.setApCommentRepays(commentRepays);
                voList.add(vo);
            }
        }
        return ResponseResult.okResult(voList);
    }
    @Autowired
    private IApCommentRepository commentRepository;
    @Autowired
    private ICommentRepayService repayService;
    @Override
    public ResponseResult delete(String commentId) {
        //删除评论
        commentRepository.deleteById(new ObjectId(commentId));
        //删除评论的点赞
        Query query = new Query();
        query.addCriteria(Criteria.where("commentId").is(commentId));
        template.remove(query, ApCommentLike.class);
        //删除评论回复及回复的点赞
        Query queryRe = new Query();
        queryRe.addCriteria(Criteria.where("entryId").is(commentId));
        List<ApCommentRepay> apCommentRepays = template.find(queryRe, ApCommentRepay.class);
        if (!CollectionUtils.isEmpty(apCommentRepays)) {
            for (ApCommentRepay apCommentRepay : apCommentRepays) {
                repayService.delete(apCommentRepay.getEntryId());
            }
        }
        //发送kafka,评论数减1
        UpdateCommentMessage message = new UpdateCommentMessage();
        message.setAdd(-1);
        message.setCommentId(commentId);
        message.setType(2);
        String jsonString = JSON.toJSONString(message);
        kafkaTemplate.send("comment_repay_score_topic", jsonString);
        return ResponseResult.okResult();
    }
}
